package router;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.Enumeration;

import dataStructures.Adjacencies;
import dataStructures.LSDataBase;
import dataStructures.NeighborTable;
import dataStructures.RoutingTable;

/**
 * Diese Klasse stellt einen Router dar und ist die zentrale Klasse. Sie verwaltet alle wichtigen Datenstrukturen.
 * @author pascal
 *
 */

public class Router {
	
	private RoutingTableInterface routingTable;
	private RoutingTable internalRoutingTable;
	private NeighborTable neighbors;
	private Adjacencies adjacencies;
	private LSDataBase database;
	private Interface firstInterface;
	private Interface secondInterface;
	private InetAddress RouterID;
	
	private static Router instance = null;
	public void run(){
		
		firstInterface.run();
		
	}
	
	private Router(){
		
		internalRoutingTable = RoutingTable.getInstance(); 
		neighbors = NeighborTable.getInstance();
		adjacencies = Adjacencies.getInstance();
		database = LSDataBase.getInstance();
		
	}
	
	public InetAddress getRouterID(){
		return this.RouterID;
	}
	
	/**
	 * Konfiguriert die Interfaces des  Router und frägt Netzwerkkarte, IP Adresse, Netzwerkmase, AreaID und Kosten ab.
	 * @throws IOException
	 */
	public void configure() throws IOException{
		
		
		Enumeration<NetworkInterface> netInter = NetworkInterface.getNetworkInterfaces();
		int n = 1;
		int display = 1;
		int interface1;
		int ip1;
		int ip2;
		int interface2;
		
		
		// Anzeigen aller Netzwerkkarten des Geräts
		while(netInter.hasMoreElements()){
			
			 NetworkInterface ni = netInter.nextElement(); 
			 
			  System.out.println( "NetworkInterface " + n++ + ": " + ni.getDisplayName() ); 
			 
			  for ( InetAddress iaddress : Collections.list(ni.getInetAddresses()) ) 
			  {
				  
				
			    System.out.println( "CanonicalHostName " +display++ +": " + 
			                         iaddress.getCanonicalHostName() ); 
			 
			    System.out.println( "IP: " + iaddress.getHostAddress() ); 
			 
			     System.out.println( "Loopback? " + iaddress.isLoopbackAddress() ); 
			     System.out.println( "SiteLocal? " + iaddress.isSiteLocalAddress() ); 
			     System.out.println(); 
			  } 
		}
		
		
		//Daten für Interface1 abfragen
		BufferedReader inp = new BufferedReader(new InputStreamReader(System.in));
		System.out.println("Geben Sie den Namen der Netzwerkkarte ein, die dem Router als Interface1 dienen soll: " );
		String dev = inp.readLine();
		
		
		//Interface1 erzeugen: benötigt wird Netzwerkkarte, Adresse, AreaID, NetzwerkTyp, netzwerkMaske
		NetworkInterface interf1 = NetworkInterface.getByName(dev);
		System.out.println(interf1.toString());
	
			//Addresse, NetzwerkMaske
			System.out.println("Welche Adresse soll verwendet werden (beginngned bei 0)?");
			int address = Integer.parseInt(inp.readLine());
			InetAddress ipAddress = interf1.getInterfaceAddresses().get(address).getAddress();
			short networkMask = interf1.getInterfaceAddresses().get(address).getNetworkPrefixLength();
		
		
			System.out.println("Geben Sie die AreaID des Router-Interfaces an: ");
			int areaID = Integer.parseInt(inp.readLine());
		
			System.out.println("Geben Sie den NetzwerkTyp an. Verfügbar sind folgende Typen: broadcast, " +
				"pointToPoint, nbma, pointToMultiPoint, virtualLink");
			String type = inp.readLine();
		
			System.out.println("Geben Sie die Kosten für ausgehende Pakete des RouterInterfaces aus: ");
			int cost = Integer.parseInt(inp.readLine());
		
			System.out.println("Interface 1 wurde mit folgenden Daten konfiguriert: ");
			System.out.println("Netzwerkkarte: " + interf1.getDisplayName());
			System.out.println("NetzwerkMaske:  " + networkMask);
			System.out.println("Adresse:  " +ipAddress.toString());
			System.out.println("AreaID: " + areaID);
			System.out.println("Netzwerktyp " + type);
			System.out.println("Kosten " + cost);
		
			this.firstInterface = new Interface(areaID, type, cost, interf1, ipAddress, networkMask   );
			this.RouterID = firstInterface.getInterfaceID();
	}
		
		
	
	public static Router getRouter(){
		if(instance == null){
			instance = new Router();
		}
		return instance;
	}
	

}
